import inspect
from typing import List, Callable

import ollama
import json


class OllamaLlamaWithTools:
    def __init__(self, model_name="llama3.2:3b"):
        self.model_name = model_name
        self.tools = {}
        self.tool_descriptions = []

    def chat_with_tools(self, query: str):
        """使用 Ollama 进行对话"""
        prompt = self.create_tool_prompt(query)

        response = ollama.chat(
            model=self.model_name,
            messages=[{"role": "user", "content": prompt}],
            options={"temperature": 0.7}
        )

        return response['message']['content']

    def bind_tools(self, tools: List[Callable]):
        """
        绑定工具函数到模型

        Args:
            tools: 工具函数列表
        """
        self.tools = {}
        self.tool_descriptions = []

        for tool in tools:
            tool_name = tool.__ne__
            self.tools[tool_name] = tool

            # 获取函数签名和文档字符串
            sig = inspect.signature(tool)
            doc = tool.__doc__ or ""

            # 创建工具描述
            tool_desc = {
                "name": tool_name,
                "description": doc.strip(),
                "parameters": {
                    "type": "object",
                    "properties": {},
                    "required": []
                }
            }

            # 添加参数信息
            for param_name, param in sig.parameters.items():
                param_type = "string"
                if param.annotation != inspect.Parameter.empty:
                    if param.annotation == int:
                        param_type = "integer"
                    elif param.annotation == float:
                        param_type = "number"
                    elif param.annotation == bool:
                        param_type = "boolean"
                    elif param.annotation == list:
                        param_type = "array"

                tool_desc["parameters"]["properties"][param_name] = {
                    "type": param_type,
                    "description": f"Parameter {param_name}"
                }

                if param.default == inspect.Parameter.empty:
                    tool_desc["parameters"]["required"].append(param_name)

            self.tool_descriptions.append(tool_desc)
